home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
C/C++ Users Group Library 1996 July
/
C-C++ Users Group Library July 1996.iso
/
listings
/
v_09_01
/
9n01114a
< prev
next >
Wrap
Text File
|
1990-11-27
|
37KB
|
1,472 lines
/*0*********************************************************
* Richard Carver July 1990
*
* This program demonstrates interprocess communication
* between several tasks using the iRMX II Operating
* System.
*
* Two tasks are used for resource control. The
* clock_task() controls use of the hardware clock and the
* crt_task() controls use of the display screen.
*
* The count_task() competes with the clock_task() for
* use of the crt_task() services. The timer_task() uses
* the services of the clock_task() for a software timer.
*
* The initial task, main(), starts every thing up and,
* when the timer_task() finishes, shuts everything down.
***********************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <rmxc.h> /* iRMX OS calls & structures */
#include <rmxerr.h> /* iRMX status codes (defines) */
#include <delay.h> /* Hardcoded delay loop macros */
#define ERROR (0xFFFF) /* Error Condition */
#define FALSE (0)
#define TRUE (!FALSE)
#define MAX_CLOCK_RETRIES (4)
/* The NULL token (similar to NULL pointer) */
#define NUL_TKN ((selector)0)
/* Options for rqgettasktokens() */
#define THIS_TASK (0x00)
#define THIS_JOB (0x01)
#define PARAM_OBJ (0x02)
#define ROOT_JOB (0x03)
/* Options for rqcreatemailbox() */
#define FIFO_OBJ_MBX (0x0000)
#define PRIORITY_OBJ_MBX (0x0001)
#define FIFO_DATA_MBX (0x0020)
#define PRIORITY_DATA_MBX (0x0021)
/* Options for rqcreatesemaphore() */
#define FIFO_SEM (0x0000)
#define PRIORITY_SEM (0x0001)
#define SEM_INIT_0 (0)
#define SEM_MAX_1 (1)
/* Common wait times for iRMX System Calls */
#define NO_WAIT (0x0000)
#define WAIT_FOREVER (0xFFFF)
/* Options for rqcreatetask() */
#define NO_FLOAT (0x0000)
#define DEFAULT_STACK_SIZE ((unsigned int)2048)
/* Task Priorities */
#define CLOCK_TASK_PRIORITY ((unsigned char)48)
#define TIMER_TASK_PRIORITY ((unsigned char)150)
#define CRT_TASK_PRIORITY ((unsigned char)200)
#define COUNT_TASK_PRIORITY ((unsigned char)200)
/* Defines For Hardware Clock */
/* Clock Interrupt Level */
#define CLOCK_INT_LEVEL (0x26)
/* Clock Ports */
#define ADR_PORT ((unsigned short)0xA060)
#define DAT_PORT ((unsigned short)0xA062)
#define CNT_PORT ((unsigned short)0xA064)
#define PIO_PORT ((unsigned short)0xA066)
/* Clock Port I/O Operations */
#define PIO_READ ((unsigned char)0x82)
#define PIO_WRITE ((unsigned char)0x80)
/* Clock Registers */
#define SEC01_REG (0x00)
#define SEC10_REG (0x01)
#define MIN01_REG (0x02)
#define MIN10_REG (0x03)
#define HRS01_REG (0x04)
#define HRS10_REG (0x05)
#define DAT01_REG (0x07)
#define DAT10_REG (0x08)
#define MON01_REG (0x09)
#define MON10_REG (0x0A)
#define YRS01_REG (0x0B)
#define YRS10_REG (0x0C)
/* Clock Control Lines */
#define CNT_RST ((unsigned char)0x00)
#define INT_ENB ((unsigned char)0x20)
#define HOLD_HIGH ((unsigned char)0x10)
#define HOLD_READ ((unsigned char)0x30)
#define HOLD_WRITE ((unsigned char)0x50)
/* Defines for months */
#define JANUARY (1)
#define FEBRUARY (2)
#define MARCH (3)
#define DECEMBER (12)
/* Time/Date and Timers Data Structure */
#define MAX_TIMERS (10)
struct SYS_TIME_STR
{
unsigned char change_flg;
unsigned char second;
unsigned char minute;
unsigned char hour;
unsigned char date;
unsigned char month;
unsigned char year;
struct TIMER_STR
{
unsigned char in_use;
unsigned int count;
unsigned int timeout;
selector sem_tkn;
}timer[MAX_TIMERS];
};
/* Request Message format for the Display Task */
struct CRT_REQ_STR
{
unsigned char *msg_ptr;
unsigned int row;
unsigned int col;
};
/* Object Catalog Names */
const unsigned char
clock_sem_name[] = "\011CLOCK_SEM",
init_sem_name[] = "\010INIT_SEM";
const unsigned char
time_seg_name[] = "\010TIME_SEG";
const unsigned char
crt_req_mbx_name[] = "\007CRT_MBX";
const unsigned char
crt_shtdwn_sem_name[] = "\012CRT_SHTDWN",
clock_shtdwn_sem_name[] = "\014CLOCK_SHTDWN",
count_shtdwn_sem_name[] = "\014COUNT_SHTDWN";
/* Days Per Month */
const unsigned char
days_in_month[12] =
{31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
/* Global System Time/Date Structure */
selector sys_time_seg;
struct SYS_TIME_STR *sys_time;
/* Task declarations */
void clock_task(void);
void crt_task(void);
void timer_task(void);
void count_task(void);
/* Task objects (global for debugging purposes) */
selector clock_tsk;
selector crt_tsk;
selector timer_tsk;
selector count_tsk;
/*1*********************************************************
* Task: main() (the initial task)
*
* Summary: Starts it all up and shuts it all down.
*
* Caveats: None
***********************************************************/
void main(void)
{
selector current_job; /* current job */
selector init_sem; /* initilaization sem */
selector clock_sem; /* time/date shared memory*/
selector clock_shtdwn_sem; /* clock_task() shutdown */
selector count_shtdwn_sem; /* count_task() shutdown */
selector crt_shtdwn_sem; /* crt_task() shutdown */
selector sys_time_seg; /* time/date data segment */
unsigned int status; /* iRMX condition code */
struct EXCEPTIONSTRUCT exceptioninfo;
/* Disable current task's exception handler */
rqgetexceptionhandler(&exceptioninfo, &status);
exceptioninfo.exceptionmode = 0;
rqsetexceptionhandler(&exceptioninfo, &status);
/* Get Token For Current Job */
current_job = rqgettasktokens(THIS_JOB, &status);
/* Create and catalog the semaphore used for */
/* accessing the shared clock data. */
clock_sem = rqcreatesemaphore(SEM_INIT_0,
SEM_MAX_1, PRIORITY_SEM, &status);
rqcatalogobject(current_job,
clock_sem, &clock_sem_name, &status);
/* Create and catalog the semaphore used for */
/* synchronizing tasks during initialization */
/* and shutdown. */
init_sem = rqcreatesemaphore(SEM_INIT_0,
99, FIFO_SEM, &status);
rqcatalogobject(current_job,
init_sem, &init_sem_name, &status);
/* Create and catalog the segment of memory */
/* used to hold the shared time/date data. */
sys_time_seg = rqcreatesegment(
sizeof(struct SYS_TIME_STR), &status);
rqcatalogobject(current_job,
sys_time_seg, &time_seg_name, &status);
/* Create and catalog the semaphores used to */
/* signal task shutdown. */
clock_shtdwn_sem = rqcreatesemaphore(SEM_INIT_0,
SEM_MAX_1, FIFO_SEM, &status);
rqcatalogobject(current_job,
clock_shtdwn_sem, &clock_shtdwn_sem_name, &status);
crt_shtdwn_sem = rqcreatesemaphore(SEM_INIT_0,
SEM_MAX_1, FIFO_SEM, &status);
rqcatalogobject(current_job,
crt_shtdwn_sem, &crt_shtdwn_sem_name, &status);
count_shtdwn_sem = rqcreatesemaphore(SEM_INIT_0,
SEM_MAX_1, FIFO_SEM, &status);
rqcatalogobject(current_job,
count_shtdwn_sem, &count_shtdwn_sem_name, &status);
/* Create the crt_task(). Wait for the task to */
/* indicate it has completed initialization. */
crt_tsk = rqcreatetask(CRT_TASK_PRIORITY, &crt_task,
NUL_TKN, NULL, DEFAULT_STACK_SIZE, NO_FLOAT, &status);
rqreceiveunits(init_sem, 1, WAIT_FOREVER, &status);
/* Create the clock_task(). Wait for the task */
/* to indicate it has completed initialization. */
clock_tsk = rqcreatetask(CLOCK_TASK_PRIORITY, &clock_task,
NUL_TKN, NULL, DEFAULT_STACK_SIZE, NO_FLOAT, &status);
rqreceiveunits(init_sem, 1, WAIT_FOREVER, &status);
/* Create the count_task(). Wait for the task */
/* to indicate it has completed initialization. */
count_tsk = rqcreatetask(COUNT_TASK_PRIORITY, &count_task,
NUL_TKN, NULL, DEFAULT_STACK_S